import {
  ForbiddenException,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { CreateStudentCourseDto } from './dto/create-student-course.dto';
import { UpdateStudentCourseDto } from './dto/update-student-course.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { StudentCourse } from './entities/student-course.entity';
import { Repository } from 'typeorm';
import { LessonsSortService } from '../lessons-sort/lessons-sort.service';
import { CourseService } from '../course/course.service';
import { map, retry } from 'rxjs/operators';
import { LessonsSort } from '../lessons-sort/entities/lessons-sort.entity';

@Injectable()
export class StudentCourseService {
  constructor(
    private readonly courseService: CourseService,
    private readonly lessonsSortService: LessonsSortService,
    @InjectRepository(StudentCourse)
    private studentCourseRepository: Repository<StudentCourse>,
  ) {}

  async create(createStudentCourseDto: CreateStudentCourseDto) {
    const lessonsList = await this.lessonsSortService.findOne(
      createStudentCourseDto.lessonsSortId,
    );
    createStudentCourseDto.lessonsSorts = [lessonsList];

    const realityPeopleNumber = await this.courseService
      .transferCourse(lessonsList.course_id)
      .catch((err) => {
        throw new UnauthorizedException(err);
      });

    const selectedList = await this.findOne(createStudentCourseDto.student_id); // 已选课表

    const lessonsSort = await this.lessonsSortService.findDetail(
      createStudentCourseDto.lessonsSortId,
    ); // 拉取课程上课时间段详情

    // 判断是否选课冲突
    if (selectedList.length) {
      // 获取上课时间段
      const timeSlot_ids = lessonsSort.timeSlots.map(
        (item) => item.timeSlot_id,
      );

      for (let i = 0; i < selectedList.length; i++) {
        const item = selectedList[i];
        if (item.lessonsSorts['timeSlots'].length) {
          for (let j = 0; j < item.lessonsSorts['timeSlots'].length; j++) {
            const lessItem = item.lessonsSorts['timeSlots'][j];
            // 通过比较两个上课时间段与星期
            if (
              timeSlot_ids.find((i) => i === lessItem['timeSlot_id']) &&
              lessonsSort.week === item.lessonsSorts['week']
            ) {
              return new UnauthorizedException('与已选课程冲突');
            }
          }
        }
      }
    }

    if (realityPeopleNumber.id) {
      const res = await this.studentCourseRepository
        .save(createStudentCourseDto)
        .catch((err) => {
          return new UnauthorizedException(err);
        });
      return res;
    }
  }

  async findOne(id: number) {
    const query =
      this.studentCourseRepository.createQueryBuilder('student_course');
    const res = await query
      .leftJoinAndMapOne(
        'student_course.lessonsSorts',
        'student_course.lessonsSorts',
        'lessons_sorts',
      )
      .leftJoinAndSelect('lessons_sorts.classRoom', 'class_room')
      .leftJoinAndSelect('lessons_sorts.course', 'course')
      .leftJoinAndSelect('lessons_sorts.teacher', 'teacher')
      .leftJoinAndSelect('lessons_sorts.timeSlots', 'time_slot')
      .where('student_course.student_id = :student_id', { student_id: id })
      .getMany();
    return res;
  }

  async remove(id: number) {
    const query = await this.studentCourseRepository.findOne({
      where: { id },
    });
    if (query) {
      return this.studentCourseRepository.remove(query);
      // return {};
    } else {
      throw new ForbiddenException('失败');
    }
  }
}
